/**
 * field的基本方法，被BaseCheckGroup混合
 *@author xiaowei
 * @date 2017年4月25日
 */
Ext.define('App.view.common.FieldBaseFun',{
	config: {
        
        validation: null,

        validationField: null
    },

    validateOnChange: true,
	
    valuePublishEvent: 'change',

    suspendCheckChange: 0,
    dirty: false,
	
	initField: function() {
        var me = this,
            valuePublishEvent = me.valuePublishEvent,
            len, i;

        me.initValue();
        
        //<debug>
        var badNames = [
            'tagName',
            'nodeName',
            'children',
            'childNodes'
        ], name = this.name;
            
        if (name && Ext.Array.indexOf(badNames, name) > -1) {
            Ext.log.warn(
                ['It is recommended to not use "', name, '" as a field name, because it ',
                'can cause naming collisions during form submission.'].join('')
            );
        }
        //</debug>

        // Vast majority of cases won't be an array
        if (Ext.isString(valuePublishEvent)) {
            me.on(valuePublishEvent, me.publishValue, me);
        } else {
            for (i = 0, len = valuePublishEvent.length; i < len; ++i) {
                me.on(valuePublishEvent[i], me.publishValue, me);
            }
        }
    },

    initValue: function() {
        var me = this;

        // Set the initial value if we have one.
        // Prevent validation on initial set.
        if ('value' in me) {
            me.suspendCheckChange++;
            me.setValue(me.value);
            me.suspendCheckChange--;
        }
        
        me.initialValue = me.originalValue = me.lastValue = me.getValue();
    },

    cleanupField : function() {
        delete this._ownerRecord;
    },

    getFieldIdentifier: function () {
        return this.isEditorComponent ? this.dataIndex : this.name;
    },

    getName: function() {
        return this.name;
    },

    isEqual: function(value1, value2) {
        return String(value1) === String(value2);
    },

    isEqualAsString: function(value1, value2){
        return String(Ext.valueFrom(value1, '')) === String(Ext.valueFrom(value2, ''));
    },

    getSubmitData: function() {
        var me = this,
            data = null;
        if (!me.disabled && me.submitValue) {
            data = {};
            data[me.getName()] = '' + me.getValue();
        }
        return data;
    },

    getModelData: function(includeEmptyText, /*private*/ isSubmitting) {
        var me = this,
            data = null;
        
        if (!me.disabled && (me.submitValue || !isSubmitting)) {
            data = {};
            data[me.getFieldIdentifier()] = me.getValue();
        }
        return data;
    },

    reset: function(){
        var me = this;

        me.beforeReset();
        me.setValue(me.originalValue);
        me.clearInvalid();
        // delete here so we reset back to the original state
        delete me.wasValid;
    },
    

    beforeReset: Ext.emptyFn,

    resetOriginalValue: function() {
        this.originalValue = this.getValue();
        this.checkDirty();
    },

    checkChange: function() {
        var me = this,
            newVal, oldVal;
            
        if (!me.suspendCheckChange) {
            newVal = me.getValue();
            oldVal = me.lastValue;
                
            if (!me.destroyed && me.didValueChange(newVal, oldVal)) {
                me.lastValue = newVal;
                me.fireEvent('change', me, newVal, oldVal);
                me.onChange(newVal, oldVal);
            }
        }
    },

    didValueChange: function(newVal, oldVal){
        return !this.isEqual(newVal, oldVal);
    },

    onChange: function (newVal) {
        var me = this;

        if (me.validateOnChange) {
            me.validate();
        }

        me.checkDirty();
    },

    publishValue: function () {
        var me = this;

        if (me.rendered && !me.getErrors().length) {
            me.publishState('value', me.getValue());
        }
    },

    isDirty : function() {
        var me = this;
        return !me.disabled && !me.isEqual(me.getValue(), me.originalValue);
    },

    checkDirty: function() {
        var me = this,
            isDirty = me.isDirty();
        
        if (isDirty !== me.wasDirty) {
            me.dirty = isDirty;
            me.fireEvent('dirtychange', me, isDirty);
            me.onDirtyChange(isDirty);
            me.wasDirty = isDirty;
        }
    },


    onDirtyChange: Ext.emptyFn,


    getErrors: function (value) {
        var errors = [],
            validationField = this.getValidationField(),
            validation = this.getValidation(),
            result;

        if (validationField) {
            result = validationField.validate(value, null, null, this._ownerRecord);
            if (result !== true) {
                errors.push(result);
            }
        }

        if (validation && validation !== true) {
            errors.push(validation);
        }

        return errors;
    },

    isValid : function() {
        var me = this;
        return me.disabled || Ext.isEmpty(me.getErrors());
    },

    validate : function() {
        return this.checkValidityChange(this.isValid());
    },

    checkValidityChange: function(isValid) {
        var me = this;

        if (isValid !== me.wasValid) {
            me.wasValid = isValid;
            me.fireEvent('validitychange', me, isValid);
        }
        return isValid;
    },

    setValidationField: function(value, record) {
        this.callParent([value]);
        this._ownerRecord = record;
    },


    batchChanges: function(fn) {
        try {
            this.suspendCheckChange++;
            fn();
        }
        finally {
            this.suspendCheckChange--;
        }
        this.checkChange();
    },


    isFileUpload: function() {
        return false;
    },


    extractFileInput: function() {
        return null;
    },

    markInvalid: Ext.emptyFn,

    clearInvalid: Ext.emptyFn,

    updateValidation: function(validation, oldValidation) {
        if (oldValidation) {
            this.validate();    
        }
    },

    privates: {
        resetToInitialValue: function() {
            var me = this,
                originalValue = me.originalValue;

            me.originalValue = me.initialValue;
            me.reset();
            me.originalValue = originalValue;
        }
    }
});